//
// Created by 党清浩 on 2021/10/22.
//

#include <stdio.h>

#define MAXSIZE 50
#define TRUE 1
#define FALSE 0

typedef int QueueElementType;
//定义链对
typedef struct {
    QueueElementType element[MAXSIZE];
    //队头
    int front;
    //队尾
    int rear;
} SeqQueue;


//链队列初始化
void InitQueue(SeqQueue *Q);

//链对入列操作
int EnterQueue(SeqQueue *Q, QueueElementType x);

//链对出列操作
int DeleteQueue(SeqQueue *Q, QueueElementType *x);

//
int GetHead(SeqQueue *Q, QueueElementType *x);

//
int IsEmpty(SeqQueue *Q);

//杨辉三角实现
void YangHuitriangle(int N);


//主函数
int main() {
    int N;
    scanf("%d", &N);
    YangHuitriangle(N);
    return 0;
}

//链队列初始化
void InitQueue(SeqQueue *Q) {
    Q->front = Q->rear = 0;
}

//链对入列操作
int EnterQueue(SeqQueue *Q, QueueElementType x) {
    /*尾指针加1追上头指针，标志队列已经满了*/
    if ((Q->rear + 1) % MAXSIZE == Q->front)
        return FALSE;
    Q->element[Q->rear] = x;
    /*重新设置队尾指针*/
    Q->rear = (Q->rear + 1) % MAXSIZE;
    /*操作成功*/
    return TRUE;
}

//链对出列操作
int DeleteQueue(SeqQueue *Q, QueueElementType *x) {
    if (Q->front == Q->rear)
        return FALSE;
    *x = Q->element[Q->front];
    Q->front = (Q->front + 1) % MAXSIZE;
    return TRUE;
}

int GetHead(SeqQueue *Q, QueueElementType *x) {
    if (Q->front == Q->rear)
        return FALSE;
    *x = Q->element[Q->front];
    return TRUE;
}

int IsEmpty(SeqQueue *Q) {
    if (Q->rear == Q->front)
        return TRUE;
    else
        return FALSE;
}

void YangHuitriangle(int N) {
    int n, i, x;
    QueueElementType temp;
    SeqQueue Q;
    InitQueue(&Q);
    EnterQueue(&Q, 1);
    for (n = 2; n <= N; n++) {
        EnterQueue(&Q, 1);
        for (i = 1; i <= n - 2; i++) {
            DeleteQueue(&Q, &temp);
            printf("%-4d", temp);
            GetHead(&Q, &x);
            temp = temp + x;
            EnterQueue(&Q, temp);
        }
        DeleteQueue(&Q, &x);
        printf("%-4d", x);
        EnterQueue(&Q, 1);
        printf("\n");
    }
    while (!IsEmpty(&Q)) {
        DeleteQueue(&Q, &x);
        printf("%-4d", x);
    }
}